<script setup>
import { ref } from 'vue';

const emits = defineEmits(['update:modelValue']);
const props = defineProps({
  modelValue: {
    type: Array,
    default: () => []
  }
});
const popupRef = ref(); // 弹出层
const confirmFunc = ref(); // 成功回调
const cancelFunc = ref(); // 取消回调

const title = ref('');
const list = ref([]);
const config = ref({ label: 'label', value: 'value' });
const dataIndex = ref([]);
const params = ref([]);
const visible = ref(false);

/**
 * value   [value1, value2, ...] 回显数据
 * list    [list1, list2, ...] 数据选项
 * config  {label, value} 配置
 * confirm
 * fail
 * */
const open = ({
  title: t = '',
  value,
  options: lists,
  config: c = { label: 'label', value: 'value' },
  confirm,
  cancel
}) => {
  const values = value || props.modelValue;
  title.value = t;
  config.value = c;
  list.value = lists;
  params.value = [];
  dataIndex.value = []; // 重置，回显选中项
  for (let i = 0, len = lists.length; i < len; i++) {
    const item = lists[i];
    const index = item.findIndex(v => v[c.value] === values[i]);
    if (index >= 0) {
      dataIndex.value.push(index);
      params.value.push({
        ...item[index],
        label: item[index][c.label],
        value: item[index][c.value]
      });
    }
  }
  confirmFunc.value = confirm;
  cancelFunc.value = cancel;
  popupRef.value.open('bottom');
  visible.value = true;
};

const close = () => {
  popupRef.value.close();
};

defineExpose({ open, close });

// 切换
const onChange = ev => {
  dataIndex.value = ev.detail.value;
  params.value = [];
  let values = [...props.modelValue];
  for (let i = 0, len = ev.detail.value.length; i < len; i++) {
    const item = ev.detail.value[i];
    params.value.push({
      ...list.value[i][item],
      label: list.value[i][item][config.value.label],
      value: list.value[i][item][config.value.value]
    });
    values[i] = list.value[i][item][config.value.value];
  }
  emits('update:modelValue', values);
};

const onCancel = () => {
  cancelFunc.value && cancelFunc.value();
  close();
};

const onSubmit = () => {
  confirmFunc.value && confirmFunc.value(params.value);
  close();
};
</script>

<template>
  <uni-popup ref="popupRef" background-color="#fff" border-radius="10rpx 10rpx 0 0">
    <view class="popup-content">
      <slot name="header">
        <view class="popup-title">{{ title }}</view>
      </slot>

      <picker-view
        v-if="visible"
        :value="dataIndex"
        class="picker-view"
        indicator-style="height: 50px;"
        @change="onChange"
      >
        <picker-view-column v-for="(item, index) in list" :key="index">
          <view v-for="(val, ind) in item" :key="ind" class="item">{{ val[config.label] }}</view>
        </picker-view-column>
      </picker-view>

      <view class="popup-footer">
        <button class="button plain-button cancel-btn" hover-class="plain-hover" @click="onCancel">取消</button>
        <button class="button primary-button submit-btn" hover-class="hover" @click="onSubmit">确定</button>
      </view>
    </view>
  </uni-popup>
</template>

<style lang="scss" scoped>
.popup-content {
  padding: 24rpx 40rpx $uni-padding-bottom;

  .popup-title {
    text-align: center;
    font-weight: bold;
    font-size: 32rpx;
    color: #333333;
  }

  .popup-footer {
    display: flex;
    justify-content: center;
    align-items: center;

    .cancel-btn {
      width: 250rpx;
      height: 71rpx;
      margin-right: 40rpx;
    }

    .submit-btn {
      width: 380rpx;
      height: 71rpx;
    }
  }

  .picker-view {
    width: 100%;
    height: 600rpx;
    margin-top: 20rpx;
  }

  .item {
    display: flex;
    justify-content: center;
    align-items: center;
    line-height: 100rpx;
  }
}
</style>
